package com.common.base.app.extras

import android.annotation.SuppressLint
import android.app.Activity
import android.content.ContentResolver
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.util.Log
import android.widget.ImageView
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide
import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.load.resource.gif.GifDrawable
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory
import com.common.base.R
import com.common.base.config.AppConfig.GLIDE_FADE_IN_TIME
import com.common.base.utils.AppUtils
import com.common.base.utils.LogUtils
import com.common.base.utils.ViewUtils.getScreenWidth
import com.common.base.utils.transform.GlideRoundTransform
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.controller.ControllerListener
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.image.ImageInfo
import com.luck.picture.lib.utils.ActivityCompatHelper
import jp.wasabeef.glide.transformations.BlurTransformation
import jp.wasabeef.glide.transformations.CropCircleWithBorderTransformation
import jp.wasabeef.glide.transformations.RoundedCornersTransformation

/**
 * Glide加载图片，可以指定圆角弧度。
 *
 * @param url 图片地址
 * @param round 圆角，单位dp
 * @param cornerType 圆角角度
 */
fun ImageView.load(
    url: Any?,
    round: Float = 0f,
    @DrawableRes placeholder: Int = R.mipmap.icon_img_default,
    cornerType: RoundedCornersTransformation.CornerType = RoundedCornersTransformation.CornerType.ALL,
    listener: OnImageLoadListener? = null
) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }
    var path = url
    if (url is String) {
        path = url.getUrl()
    }

    val option = RequestOptions()
    if (round != 0f)  {
//        val option = RequestOptions.bitmapTransform(
//            RoundedCornersTransformation(dp2px(round).toInt(), 0, cornerType)
//        ).dontAnimate()
        var transformation: BitmapTransformation? = null
        // 圆角特效受到ImageView的scaleType属性影响
        if (this.scaleType == ImageView.ScaleType.FIT_CENTER ||
            this.scaleType == ImageView.ScaleType.CENTER_INSIDE ||
            this.scaleType == ImageView.ScaleType.CENTER ||
            this.scaleType == ImageView.ScaleType.CENTER_CROP
        ) {
            transformation = CenterCrop()
        }
        if (transformation == null) {
            option.transform(RoundedCornersTransformation(dp2px(round).toInt(), 0, cornerType))
        } else {
            option.transform(
                transformation,
                RoundedCornersTransformation(dp2px(round).toInt(), 0, cornerType)
            )
        }
    }

    try {
        isGif(path).yes {
            Glide.with(this.context)
                .asGif()
                .load(path)
                .apply(option)
//                .diskCacheStrategy(DiskCacheStrategy.RESOURCE)//杀进程后缓存跟随清除
                .diskCacheStrategy(DiskCacheStrategy.DATA)//杀进程后缓存还在，无网络下直接读缓存
                .placeholder(placeholder)
                .error(placeholder)
                .listener(LoadGifRequestListener(listener))
                .into(this)
        }.otherwise {

            Glide.with(this.context)
//                .asBitmap()
                .asDrawable()
                .load(path)
                .apply(option)
                .dontAnimate()
                .placeholder(placeholder)
                .error(placeholder)
//                .transition(DrawableTransitionOptions.withCrossFade())
                .transition(
                    DrawableTransitionOptions.with(
                        DrawableCrossFadeFactory.Builder(
                            GLIDE_FADE_IN_TIME
                        ).setCrossFadeEnabled(true).build()
                    )
                ) //渐入动画效果
                .listener(LoadRequestListener(listener))
                .into(this)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

fun ImageView.loadId(
    mId: Int = -1,
    round: Float = 0f,
    @DrawableRes placeholder: Int = R.mipmap.icon_img_default,
    cornerType: RoundedCornersTransformation.CornerType = RoundedCornersTransformation.CornerType.ALL,
    listener: OnImageLoadListener? = null
) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }
    val option = RequestOptions()
    if (round != 0f)  {
//        val option = RequestOptions.bitmapTransform(
//            RoundedCornersTransformation(dp2px(round).toInt(), 0, cornerType)
//        ).dontAnimate()
        var transformation: BitmapTransformation? = null
        // 圆角特效受到ImageView的scaleType属性影响
        if (this.scaleType == ImageView.ScaleType.FIT_CENTER ||
            this.scaleType == ImageView.ScaleType.CENTER_INSIDE ||
            this.scaleType == ImageView.ScaleType.CENTER ||
            this.scaleType == ImageView.ScaleType.CENTER_CROP
        ) {
            transformation = CenterCrop()
        }
        if (transformation == null) {
            option.transform(RoundedCornersTransformation(dp2px(round).toInt(), 0, cornerType))
        } else {
            option.transform(
                transformation,
                RoundedCornersTransformation(dp2px(round).toInt(), 0, cornerType)
            )
        }
    }

    Glide.with(this.context)
//        .asBitmap()
        .asDrawable()
        .load(mId)
        .apply(option)
        .dontAnimate()
        .placeholder(placeholder)
        .error(placeholder)
        .listener(LoadRequestListener(listener))
        .transition(
            DrawableTransitionOptions.with(
                DrawableCrossFadeFactory.Builder(
                    GLIDE_FADE_IN_TIME
                ).setCrossFadeEnabled(true).build()
            )
        ) //渐入动画效果
        .into(this)
}

fun loadBitmap(content: Context? = null, path: Any?, listener: OnImageLoadListener? = null) {

    doOnIOThread {
        try {
            val bitmap = Glide
                .with(content ?: AppUtils.getContext())
//                .asBitmap()
//                .asDrawable()
                .load(path)
                .transition(
                    DrawableTransitionOptions.with(
                        DrawableCrossFadeFactory.Builder(
                            GLIDE_FADE_IN_TIME
                        ).setCrossFadeEnabled(true).build()
                    )
                ) //渐入动画效果
                .apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.RESOURCE))
                .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
                .get()
            doOnUiThread { listener?.onSuccess(bitmap) }
        } catch (e: Exception) {
            listener?.onFail(e.toString())
            e.printStackTrace()
        }
    }
}

/**
 * 图片加载监听
 */
class LoadRequestListener(var listener: OnImageLoadListener?) :
    RequestListener<Drawable> {
    override fun onLoadFailed(
        e: GlideException?,
        model: Any?,
        target: Target<Drawable>,
        isFirstResource: Boolean
    ): Boolean {
        listener?.onFail(e?.localizedMessage ?: "")
        return false
    }

    override fun onResourceReady(
        resource: Drawable,
        model: Any,
        target: Target<Drawable>?,
        dataSource: DataSource,
        isFirstResource: Boolean
    ): Boolean {
        listener?.onSuccess(resource)
        return false
    }
}

/**
 * 图片加载监听
 */
class LoadGifRequestListener(var listener: OnImageLoadListener?) :
    RequestListener<GifDrawable> {
    override fun onLoadFailed(
        e: GlideException?,
        model: Any?,
        target: Target<GifDrawable>,
        isFirstResource: Boolean
    ): Boolean {
        listener?.onFail(e?.localizedMessage ?: "")
        return false
    }

    override fun onResourceReady(
        resource: GifDrawable,
        model: Any,
        target: Target<GifDrawable>?,
        dataSource: DataSource,
        isFirstResource: Boolean
    ): Boolean {
//        // 这里可以判断缓存是否存在
//        val isCached = dataSource == DataSource.MEMORY_CACHE || dataSource == DataSource.RESOURCE_DISK_CACHE
//        val isCached2 = dataSource !== DataSource.REMOTE
        if (dataSource == DataSource.MEMORY_CACHE || dataSource == DataSource.DATA_DISK_CACHE) {
            // 图像从缓存加载
            Log.d("ImageView-Glide", "Image is loaded from cache")
        } else {
            // 图像重新下载
            Log.d("ImageView-Glide", "Image is downloaded from network")
        }
        // 图片加载成功时的处理
        listener?.onSuccess(resource)
        return false
    }
}

@SuppressLint("CheckResult")
fun ImageView.loadCircle(
    url: String?,
    @DrawableRes placeholder: Int = 0,
    borderSize: Int = 0,
    @ColorInt borderColor: Int = Color.TRANSPARENT
) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }
    val option = RequestOptions.bitmapTransform(
        CropCircleWithBorderTransformation(borderSize, borderColor)
    ).dontAnimate()
    if (placeholder != 0) {
        option.placeholder(placeholder)
            .error(placeholder)

    }

    Glide.with(this.context).load(url).apply(option)
        .transition(
            DrawableTransitionOptions.with(
                DrawableCrossFadeFactory.Builder(
                    GLIDE_FADE_IN_TIME
                ).setCrossFadeEnabled(true).build()
            )
        ) //渐入动画效果
        .into(this)
}

fun ImageView.loadBlur(url: Any?, blurRadius: Int = 25, blurSampling: Int = 1) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }
    Glide.with(this.context).load(url)
        .apply(RequestOptions.bitmapTransform(BlurTransformation(blurRadius, blurSampling)))
        .transition(
            DrawableTransitionOptions.with(
                DrawableCrossFadeFactory.Builder(
                    GLIDE_FADE_IN_TIME
                ).setCrossFadeEnabled(true).build()
            )
        ) //渐入动画效果
        .into(this)
}

/**
 * Glide加载图片，可以定义配置参数。
 *
 * @param url 图片地址
 * @param options 配置参数
 */
fun ImageView.load(url: String?, options: RequestOptions.() -> RequestOptions) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }
    Glide.with(this.context).load(url).apply(RequestOptions().options())
        .transition(
            DrawableTransitionOptions.with(
                DrawableCrossFadeFactory.Builder(
                    GLIDE_FADE_IN_TIME
                ).setCrossFadeEnabled(true).build()
            )
        ) //渐入动画效果
        .into(this)
}

fun SimpleDraweeView?.loadDrawable(
    @DrawableRes resId: Int,
    listener: ControllerListener<ImageInfo>? = null
) {
    this?.let {
        val uri = Uri.parse(imageTranslateUri(it.context, resId))
        loadDrawable(uri, listener)
    }
}

fun SimpleDraweeView?.loadDrawable(
    uri: Uri?,
    listener: ControllerListener<ImageInfo>? = null
) {
    this?.let {
        val controller = Fresco.newDraweeControllerBuilder()
            .setUri(uri)
            .setAutoPlayAnimations(true)
            .setOldController(it.controller)
            .setControllerListener(listener)
            .build()
        it.controller = controller
    }
}

/**
 *
 * drawable路径转换成 url
 * @param context
 * @param resId
 * @return
 */

fun imageTranslateUri(context: Context, resId: Int): String {
    val r = context.resources
    val uri = Uri.parse(
        ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + r.getResourcePackageName(resId) + "/" + r.getResourceTypeName(
            resId
        ) + "/" + r.getResourceEntryName(resId)
    )
    return uri.toString()

}

//检查是否可以进行加载，页面销毁不加载
private fun checkCanLoad(context: Context?): Boolean {
    if(context == null){
        return false
    }
    if (context is Activity) {
        return context.isFinishing.not()
    } else if (context is Fragment) {
        return context.requireActivity().isFinishing.not()
    }
    return true
}

/**
 * 是否是GIF图
 */
fun isGif(any: Any?): Boolean {
    return if (any is String) {
        //不使用endWidth,避免有些带参数的url无法识别
        any.contains("gif", true) && !any.endsWith(".jpg") && !any.endsWith(".png")
    } else {
        false
    }
}

fun ImageView.loadRound(url: Any?, radiusDp: Int = 10) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }

    val options = RequestOptions()
        .placeholder(R.drawable.common_imge_default_icon)
        //.optionalCenterInside()
        .transform(GlideRoundTransform(radiusDp))
    Glide.with(this.context).load(url)
        .apply(options)
        .transition(
            DrawableTransitionOptions.with(
                DrawableCrossFadeFactory.Builder(
                    GLIDE_FADE_IN_TIME
                ).setCrossFadeEnabled(true).build()
            )
        ) //渐入动画效果
        .into(this)
}


/**
 * 通过Glide加载图片
 */
fun ImageView.loadBannerRound(url: Any?, radiusDp: Int = 10) {
    if (!ActivityCompatHelper.assertValidRequest(this.context)) {
        return
    }
    val options: RequestOptions = RequestOptions()
        .placeholder(R.drawable.ic_error_banner_round)
        .error(R.drawable.ic_error_banner_round)
            .disallowHardwareConfig()
            .diskCacheStrategy(DiskCacheStrategy.ALL)
        .transform(GlideRoundTransform(radiusDp))

    Glide.with(this.context) //
        .load(url) //
        .apply(options)
        .transition(
            DrawableTransitionOptions.with(
                DrawableCrossFadeFactory.Builder(
                    GLIDE_FADE_IN_TIME
                ).setCrossFadeEnabled(true).build()
            )
        ) //渐入动画效果
        .into(this)
}


/**
 * Glide加载图片，可以指定圆角弧度。
 *
 * @param url 图片地址
 * @param round 圆角，单位dp
 * @param cornerType 圆角角度
 */
fun ImageView.loadDrGif(
    url: Any?,
    @DrawableRes placeholder: Int = R.mipmap.icon_img_default_error,listener: OnImageLoadListener? = null
) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }
    var path = url
    if (url is String) {
        path = url.getUrl()
    }

    val option = RequestOptions()
    option.diskCacheStrategy.decodeCachedResource()

    try {
        Glide.with(this.context)
            .asGif()
            .load(path)
            .apply(option)
            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
            .placeholder(placeholder)
            .error(placeholder)
            .listener(LoadGifRequestListener(listener))
            .into(this)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}


/**
 * Glide加载图片，可以指定圆角弧度。
 *
 * @param url 图片地址
 * @param round 圆角，单位dp
 * @param cornerType 圆角角度
 */
fun ImageView.loadYX(
    url: Any?,
    @DrawableRes placeholder: Int = R.mipmap.icon_img_default,listener: OnImageLoadListener? = null
) {
    checkCanLoad(this.context).no {
        LogUtils.e("==>页面已销毁不加载")
        return
    }
    var path = url
    if (url is String) {
        path = url.getUrl()
    }

//    val option = RequestOptions()
//    option.diskCacheStrategy(DiskCacheStrategy.ALL)
//    option.priority(Priority.HIGH)
//    option.override(getScreenWidth(), Target.SIZE_ORIGINAL)//关键代码，加载原始大小
//        .apply(option)
    try {
        Glide.with(this.context)
            .load(path)
            .placeholder(placeholder)
            .error(placeholder)
            .skipMemoryCache(true)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .format(DecodeFormat.PREFER_RGB_565)//设置为这种格式去掉透明度通道，可以减少内存占有
            .override(getScreenWidth(), Target.SIZE_ORIGINAL)//关键代码，加载原始大小
            .listener(LoadRequestListener(listener))
            .into(this)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

interface OnImageLoadListener {
    fun onSuccess(bitmap: Drawable?)
    fun onFail(msg: String)
}

open class SimpleOnImageLoadListener : OnImageLoadListener {
    override fun onSuccess(bitmap: Drawable?) {
    }

    override fun onFail(msg: String) {
    }
}